package indi.zhifa.engine.starter.web;

import com.alibaba.fastjson2.support.config.FastJsonConfig;
import com.alibaba.fastjson2.support.spring6.http.converter.FastJsonHttpMessageConverter;
import indi.zhifa.engine.core.common.config.FastjsonConfig;
import indi.zhifa.engine.core.common.utils.TimeUtil;
import indi.zhifa.engine.core.common.web.CommonInit;
import indi.zhifa.engine.core.common.web.aop.ExceptionHandle;
import indi.zhifa.engine.core.common.web.aop.GlobalRestfulResponseBodyAdvice;
import indi.zhifa.engine.core.common.web.resttemplate.HttpProperties;
import indi.zhifa.engine.core.common.web.resttemplate.SSL;
import indi.zhifa.engine.core.common.web.utils.SpringUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.core.convert.converter.Converter;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.FormHttpMessageConverter;

import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@RequiredArgsConstructor
@AutoConfiguration
@ConditionalOnProperty(prefix = "zhifa.web", name = "enabled", havingValue = "true")
public class WebCommonStarterConfig {

    @Bean
    @ConditionalOnMissingBean
    public CommonInit commonInit() {
        CommonInit commonInit = new CommonInit();
        return commonInit;
    }

    @Bean
    @ConditionalOnMissingBean
    public ExceptionHandle webExceptionHandle() {
        ExceptionHandle exceptionHandle = new ExceptionHandle();
        return exceptionHandle;
    }

    @Bean
    @ConditionalOnMissingBean
    public GlobalRestfulResponseBodyAdvice globalRestfulResponseBodyAdvice() {
        return new GlobalRestfulResponseBodyAdvice();
    }

    @Bean
    public Converter<String, LocalDateTime> localDateTimeConvert() {
        return new Converter<String, LocalDateTime>() {
            @Override
            public LocalDateTime convert(String source) {
                return TimeUtil.convertToLocalDateTime(source);
            }
        };
    }

    @Bean
    public Converter<String, LocalDate> localDateConvert() {
        return new Converter<String, LocalDate>() {
            @Override
            public LocalDate convert(String source) {
                return TimeUtil.convertToLocalDate(source);
            }
        };
    }

    @Bean
    public Converter<String, LocalTime> localTimeConvert() {
        return new Converter<String, LocalTime>() {
            @Override
            public LocalTime convert(String source) {
                return TimeUtil.convertToLocalTime(source);
            }
        };
    }

    @Primary
    @Bean(name = "default-fastJson-config")
    public FastJsonConfig defaultFastJsonConfig() {
        return FastjsonConfig.getDefaultFastJsonConfig();
    }

    @Bean(name = "simple-fastJson-config")
    public FastJsonConfig simpleFastJsonConfig() {
        return FastjsonConfig.getSimpleFastJsonJsonConfig();
    }

    @Bean(name = "serialize-fastJson-config")
    public FastJsonConfig serializeFastJsonConfig() {
        return FastjsonConfig.getSerializeFastJsonConfig();
    }


    @Primary
    @Bean(name = "default-message-converter")
    public FastJsonHttpMessageConverter getFastJsonHttpMessageConverter(FastJsonConfig pFastJsonConfig) {

        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        converter.setDefaultCharset(StandardCharsets.UTF_8);
        converter.setFastJsonConfig(pFastJsonConfig);
        List<MediaType> mediaTypeList = new ArrayList<>();
        // 解决中文乱码问题，相当于在 Controller 上的 @RequestMapping 中加了个属性 produces = "application/json"
        mediaTypeList.add(MediaType.APPLICATION_JSON);
        //mediaTypeList.add(MediaType.TEXT_HTML);
        converter.setSupportedMediaTypes(mediaTypeList);
        return converter;
    }

    @Bean(name = "sse-message-converter")
    public FastJsonHttpMessageConverter getFastJsonHttpMessageConverterForSSE(@Qualifier(value = "simple-fastJson-config") FastJsonConfig pFastJsonConfig) {

        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        converter.setDefaultCharset(StandardCharsets.UTF_8);
        converter.setFastJsonConfig(pFastJsonConfig);
        List<MediaType> mediaTypeList = new ArrayList<>();
        // 解决中文乱码问题，相当于在 Controller 上的 @RequestMapping 中加了个属性 produces = "application/json"
        mediaTypeList.add(MediaType.TEXT_EVENT_STREAM);
        converter.setSupportedMediaTypes(mediaTypeList);
        return converter;
    }

    @Bean
    SpringUtil springUtil() {
        return new SpringUtil();
    }

    @Primary
    @Bean(name = "appRestClient")
    public RestTemplate getRestClient(ClientHttpRequestFactory pClientHttpRequestFactory, FastJsonHttpMessageConverter pFastJsonHttpMessageConverter) {
        FormHttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter();
        formHttpMessageConverter.addSupportedMediaTypes(MediaType.MULTIPART_FORM_DATA);
        ByteArrayHttpMessageConverter byteArrayHttpMessageConverter = new ByteArrayHttpMessageConverter();
        byteArrayHttpMessageConverter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.IMAGE_JPEG, MediaType.IMAGE_PNG,MediaType.IMAGE_GIF, MediaType.ALL));

        RestTemplateBuilder restTemplateBuilder = new RestTemplateBuilder()
                .messageConverters(pFastJsonHttpMessageConverter, formHttpMessageConverter, byteArrayHttpMessageConverter)
                .setConnectTimeout(Duration.ofSeconds(2))
                .setReadTimeout(Duration.ofSeconds(5));
        RestTemplate restTemplate = restTemplateBuilder.build();
        restTemplate.setRequestFactory(pClientHttpRequestFactory);
        return restTemplate;
    }

    @ConfigurationProperties(prefix = "zhifa.web.http")
    @Bean
    public HttpProperties httpProperties(){
        return new HttpProperties();
    }

    @Bean
    public ClientHttpRequestFactory simpleClientHttpRequestFactory(HttpProperties pHttpProperties) {
        SSL factory = new SSL(); //这里使用刚刚配置的SSL
        // SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setReadTimeout(pHttpProperties.getReadTimeout());//单位为ms
        factory.setConnectTimeout(pHttpProperties.getConnTimeout());//单位为ms
        return factory;
    }


}
